﻿#ifndef SAPMSGINTERFACE_H
#define SAPMSGINTERFACE_H

#include <QObject>
#include<QNetworkReply>
#include<QNetworkRequest>
#include<QJsonObject>
#include<QJsonArray>
#include<QUrl>
#include<QJsonDocument>
#include<QMap>
#include <QMutex>
#include<QtXml>
#include<QtCore/QCoreApplication>
#include<QDomDocument>

#include "getinstancedefine.h"
#include "comm/config/cfgsetting.h"
#include "singleProject/single_project.h"
#include "queryServer/queryserver.h"
#include "comm/datebaseConnectPool/connectpoolfactory.h"

struct WebServiceItiem
{
    QString userBadge="";       // 员工工号
    QString LabelNo="";
    QString actionType="";      // 操作类型 WS01 WS02 WS03 ……
    QString ikey="";            // 唯一键
    QString UrlPath="";         //路径
    int restcount=0;            //发送计数 最多三次
    int sationId = 0;           //相机查询站点ID

    QString positionCode="";    //特殊ikey

    QJsonObject queryJson;      // JSON 请求数据 WS02,WS05
    QDomDocument doc;           // xml 请求数据 WS04
    QJsonArray postArray;       //WS06
    QNetworkReply *NetworkRepItiem; //网络回复
};

//
struct retMsgStruct{
    QString iKey="";
    QString result=""; //"result":"S",           //结果, S为成功, E为错误
    QString message="";//"message":""            //系统讯息
    QString errorType="0";//错误类型
};


struct sapPath_Print{
   int PathID;          //打印路径
   QString IssueType;   //发料类型
   QString printer;     //打印机型号
   QString input_type;  //打印类型
};

struct WebService{
    QString LabelNo;
    QString UserBadge;
    int pathId;
    int stationId;
};

/*******微网优联  MES************/
struct WWYLPOST{
    QString actionId="MES接口";
    QString taskId="";          //任务 ID,唯一性
    QString taskType="";        //任务类型(OUT 出库，MOVE 点对点IN 入库)
    QString boxNo="";           //料框编号，非必填（可以输入产品编码获取料框）
    QString proNo="";           //工单号
    QString boxNum="";          //料箱数量(入库时默认是1,出库时>0)
    QString source="";          //移库为起始库位(入库，出库为空)
    QString destination="";     //移库为目标库位，出库为线体(入库可指定库位入库，否则为空)

    //状态反馈
    QString taskStatus="";//任务状态
    QString taskStatusDesc="";//任务状态
};

struct ESS_AGV{

    QString taskId="";              //订单编码唯一
    int taskType=0;                 //任务类型  1入料 2出料 3呼叫空架
    int agvId=0;                    //AGV编号
    int priority=0;                 //优先级
    int finishNode=0;               //完成返回点

    int load=0;                     //装机站点
    int loadWaitNode=0;             //装机站点 等待点
    int loadAnglePose=0;            //姿态角度
    int loadAngleRotary=0;          //顶盘角度

    int unload=0;                   //装机站点
    int unloadWaitNode=0;           //装机站点 等待点
    int unloadAnglePose=0;          //姿态角度
    int unloadAngleRotary=0;        //顶盘角度

    int workStation=0;              //装机站点
    int workWaitStation=0;          //装机站点 等待点
    int workAnglePose=0;            //姿态角度
    int workAngleRotary=0;          //顶盘角度

    int work2Station=0;             //装机站点
    int work2WaitStation=0;         //装机站点 等待点
    int work2AnglePose=0;           //姿态角度
    int work2AngleRotary=0;         //顶盘角度

};

/*******海柔************/
struct ESS_Request{

    QString iKey="";
    int pathId=0;
    QString actionId="";//0查询状态  1任务查询  2出库  3移库  4回库  5任务取消

/********** 状态查询 ************/
    QString robotCode="";
    QList<QString>robotCodes; //机器人查询接口
    QList<QString>taskCodes;  //任务查询接口

/********** 任务指令 ************/
    QString taskId="";              //订单编码唯一
    QString taskType="";            //任务类型  1入料 2出料 3呼叫
    int agvId=0;                    //配送小车编号
    int priority=100;               //任务优先级
    QString load="";                //装机站点
    QString loadWaitNode="";        //装机站点 等待点
    QString workStation="";         //老化工位
    QString unload="";              //下机站点
    QString unloadWaitNode="";      //下机站点 等待点
    QString finishNode="";          //完成返回站点 等待点
    int WaitStation=0;         //临时等待点

    ESS_AGV ESS_AGV0;

    /****** 任务状态反馈给 MES ***********/
    int status=0;                   //任务状态
    QString message="";             //任务状态 注释

};

struct ESS_Repost{

    QString timer_str="";      //唯一标识 时间戳
    QString eventCode_="";      //ESS-P 事件 回调类型
    QString eventCodeDesc="";  //ESS-P 事件 回调类型  注释
    QString taskCode="";       //任务号
    QString taskStatus="";     //任务状态
    QString actionCode="";     //任务行为编号 (LOAD取箱成功)
    QString robotCode="";      //机器人编码
    QString containerCode="";  //货箱编码
    QString trayLevel="";      //背篓层号
    QString stationCode="";    //工作站编码
    QString locationCode="";   //入库取箱:库位编码  出库放箱: 工作位编码
    QString positionCode="";   //位置编码

    eventCode eventCodeI;
    QMap<QString,int>containerCode_Tray;//货箱编码-背篓序号  (在机器人到达工作站时)

};




//(备注: 任务执行过程中,取箱与放箱操作可重复执行,用于任务异常时，人工纠正后可继续执行)

//出库:-1 默认值  0开始执行  1ESS前往取箱  2到达工作站  3容器到位  4取箱成功  5离开工作站  6放箱成功  7任务完成


//入库:-1 默认值  0开始执行  1ESS前往工作站  2到达工作站  3容器到位  4取箱成功  5离开工作站  6放箱成功  7任务完成


struct ESS_Reply{
    int actionId;//0查询状态  1任务查询  2出库  3移库  4回库  5任务取消

    QString taskCode;       //任务号
    int code;       // 0 代表正常，其余代表异常
    QString msg;
    QString data;   //返回数据对象，如果需要(任务号 货箱编码)
};

struct CurrentSend{
    QString UrlPath="";
    QJsonObject postJson;
    QDomDocument postdoc;           // xml 请求数据

    QString Errorinfo="";
    QByteArray ReplyData;
};


class sapMsgInterface : public QObject
{
    Q_OBJECT
private:
    explicit sapMsgInterface(QObject *parent = nullptr);

public:
    REGISTERGETINSTANCE(sapMsgInterface)

    //static sapMsgInterface* getInstance();
    QTimer *MsgTimer;
    QMap<int ,sapPath >sapPathMap;
    QMap<QString ,int>currentIkeyMap;//SAP 数据 错误计时  最多只发 3次

    QMap<QString,WebService>WebServiceMap;//待 请求

    void setSapPathMap();           //读取数据库的路径配置信息

    QMap<int ,sapPath > getsapPathMap();//获取数据库的路径配置信息
    void setLabelMsgclear();//取消查询sap接口任务任务

public slots:

    //读取服务器回复
    void ReadResponse(QNetworkReply *Reply);
    void sapMsgTimer();
    void ONReplyError(WebServiceItiem WebServiceItiemI);//重复发送机制

public:
    //返回数据解析  actionType= "0" 失败
    void analysReplyJson(QString iKey,QJsonDocument JsonAnalyse,QString actionType,QString positionCode);

public:

    //<<<<<<<<<<WS01 Request <<<<<<<<<<<<
    QMap<QString,ESSRobot>labelMsgStructMap;
    void getLabelMsg(QString LabelNo, QString UserBadge,int pathI,int station);

    //<<<<<<<<<< POST 接口返回 <<<<<<<<<<<<
    QMap<QString,ReplyMsg>ReplyMsgMap;
    void ReplyJson_Msg_MES(QString iKey, QJsonObject ReplyJson,QString actionType);//MES 接口返回

    void ReplyJson_Msg_ESS(QString iKey, QJsonObject ReplyJson,QString actionType,QString positionCode);//ESS 接口返回

    ReplyMsg GetMsgRecv_Msg(QString iKey);


    //<<<<<<<<<<ESS Reply<<<<<<<<<<<<

    /***  微网优联 任务下达 以及状态返回***/
    void taskCodes_MES(QString iKey,ESS_Request ESS_RequestI,QString UserBadge,int pathId);
    QJsonObject posttaskCodes_MES(QString iKey,ESS_Request ESS_RequestI);

    /***ESS_P协议: 0查询状态  1任务查询  2出库  3移库  4回库  5任务取消***/
    QMap<QString ,ESS_Request>ESS_RequestMap;

    //机器人查询接口
    void robotCodes_query(QString iKey,ESS_Request ESS_RequestI,QString UserBadge,int pathId);
    void robotCodes_query_Get(QString iKey,ESS_Request ESS_RequestI,QString UserBadge,int pathId);
    QJsonObject postrobotCodes_query(QString iKey,ESS_Request ESS_RequestI);

    //任务查询接口
    void taskCodes_query(QString iKey,ESS_Request ESS_RequestI,QString UserBadge,int pathId);
    QJsonObject posttaskCodes_query(QString iKey,ESS_Request ESS_RequestI);

    //向查询相机库位状态         //iKey:时间戳
    void cameraCodes_query_Get(QString iKey,int stationId,int pathId);

    //2出库  3移库  4回库
    void taskCodes_actionId(QString iKey,ESS_Request ESS_RequestI,QString UserBadge,int pathId,QString Type);
    QJsonObject posttaskCodes_actionId(QString Type,ESS_Request ESS_RequestI);

    //任务取消
    void taskCodes_cancel(QString iKey,ESS_Request ESS_RequestI,QString UserBadge,int pathId);
    QJsonObject posttaskCodes_cancel(QString iKey,ESS_Request ESS_RequestI);

    /****************** 广州蔡司 *******************/
    QJsonObject JsonTaskAgvMove(SAPExcelInfo SAPExcelInfoI, int station, QString taskType, int moveFlag = 0, bool flag = false);    // AGV 移动任务参数
    void PostTaskAgvMove(SAPExcelInfo SAPExcelInfoI, int node, QString taskType, int moveFlag = 0, bool flag = false);                    // AGV 移动任务下发

    QJsonObject JsonTaskAgvAction(SAPExcelInfo SAPExcelInfoI, int station, int actionCode, QString taskType, int moveFlag = 0, bool flag = false);  // AGV 动作任务参数 内部动作
    QJsonObject JsonTaskAgvAction_1(SAPExcelInfo SAPExcelInfoI, int station, int actionCode, QString taskType, int moveFlag = 0, bool flag = false);  // AGV 动作任务参数 自定义动作
    void PostTaskAgvAction(SAPExcelInfo SAPExcelInfoI, int node, int actionCode, QString taskType, int moveFlag = 0, bool flag = false);  // AGV 滚筒动作任务下发

    QJsonObject JsonTaskAgvRunAction(SAPExcelInfo SAPExcelInfoI);                                               // AGV 滚筒动作放行任务参数
    void PostTaskAgvRunAction(SAPExcelInfo SAPExcelInfoI);                                                      // AGV 滚筒动作放行任务下发

    QJsonObject JsonTaskAgvCancel(SAPExcelInfo SAPExcelInfoI);                                                  // AGV 取消任务参数
    void PostTaskAgvCancel(SAPExcelInfo SAPExcelInfoI);                                                         // AGV 取消任务下发

    void PostTaskAgvMusic(int AgvNum, int MusicNum);                                                            // AGV 设置语音任务下发

    void PostTaskAgvClearTraffControlTask(int AgvNum);                                                          // AGV 清除所有管制任务下发

    void PostTaskAgvCancelTask(int AgvNum);                                                                     // AGV 清除所有任务指令任务下发

signals:
    void ReplyWebService(QJsonObject RequestJson, QJsonObject ReplyJson,QString UserBadge,QString ActionType);

    void ReplyError(WebServiceItiem WebServiceItiemI);


private:

    QNetworkAccessManager NetworkMgr;
    QList<WebServiceItiem > WebServiceItiemList;

//  static QMutex mutex;
//  static sapMsgInterface* instance;

    QList<WebServiceItiem>WebServiceItiemMap;

    //Get SAP 数据
    void setWebService_Get(QString LabelNo,QString UrlPath,QString UserBadge,QString Type);

    //Get SAP 数据
    void setWebService_Get_Camera(QString LabelNo,QString UrlPath,QString Type);


    //post 数据给 SAP
    void setWebService_Post(QString iKey,QString UrlPath,QJsonObject postJson,
                            QString UserBadge,QString Type,QString positionCode);

    //post 数据给 SAP
    void setWebService_Post_WS06(QString iKey,QString UrlPath,QJsonArray postJson,
                            QString UserBadge,QString Type);


    //post 数据给 SAP
    void setWebService_SAOP_Post(QString iKey,QString UrlPath,QDomDocument doc,
                            QString UserBadge,QString Type);


public:
   int currentsapPath=17;//SAP路径选择
   int WebConut=2;int allWebConut=0;

};

#endif // SAPMSGINTERFACE_H
